using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace APP.QUANLY.Common
{
    public class Security
    {
        //encrypt fun takes the string to be encrypted and passward as a parameter and
        //return encrypted string 
        static string PasswKeyToEncrypt = "ThinhTP";

        public static string ToEncrypt(string p_plainText, string p_passPhrase, string p_salt)
        {
            try
            {
                string t_salt = p_salt;        // can be any string
                string t_hashAlgorithm = "SHA1";             // can be "MD5"
                int t_passwordIterations = 2;                  // can be any number
                string t_initVector = "51cgc5D4e5F6gbc43"; // must be 16 bytes
                int t_keySize = 256;                // can be 192 or 128



                byte[] initVectorBytes = Encoding.ASCII.GetBytes(t_initVector);
                byte[] saltBytes = Encoding.ASCII.GetBytes(t_salt);


                byte[] plainTextBytes = Encoding.UTF8.GetBytes(p_plainText);

                PasswordDeriveBytes password = new PasswordDeriveBytes(
                    p_passPhrase,
                    saltBytes,
                    t_hashAlgorithm,
                    t_passwordIterations);

                byte[] keyBytes = password.GetBytes(t_keySize / 8);

                RijndaelManaged symmetricKey = new RijndaelManaged();

                symmetricKey.Mode = CipherMode.CBC;



                ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
                    keyBytes,
                    initVectorBytes);

                MemoryStream memoryStream = new MemoryStream();

                CryptoStream cryptoStream = new CryptoStream(memoryStream,
                    encryptor,
                    CryptoStreamMode.Write);

                cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);


                cryptoStream.FlushFinalBlock();


                byte[] cipherTextBytes = memoryStream.ToArray();


                memoryStream.Close();
                cryptoStream.Close();


                string t_cipherText = Convert.ToBase64String(cipherTextBytes);


                return t_cipherText;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        public static string Decrypt(string p_cipherText, string p_passPhrase, string p_salt)
        {
            try
            {
                string t_salt = p_salt;
                string t_hashAlgorithm = "SHA1";
                int t_passwordIterations = 2;
                string t_initVector = "51cgc5D4e5F6gbc43";
                int t_keySize = 256;


                byte[] initVectorBytes = Encoding.ASCII.GetBytes(t_initVector);
                byte[] saltBytes = Encoding.ASCII.GetBytes(t_salt);


                byte[] cipherTextBytes = Convert.FromBase64String(p_cipherText);

                PasswordDeriveBytes password = new PasswordDeriveBytes(
                    p_passPhrase,
                    saltBytes,
                    t_hashAlgorithm, t_passwordIterations);


                byte[] keyBytes = password.GetBytes(t_keySize / 8);

                RijndaelManaged symmetricKey = new RijndaelManaged();


                symmetricKey.Mode = CipherMode.CBC;


                ICryptoTransform decryptor = symmetricKey.CreateDecryptor(
                    keyBytes,
                    initVectorBytes);

                MemoryStream memoryStream = new MemoryStream(cipherTextBytes);


                CryptoStream cryptoStream = new CryptoStream(memoryStream,
                    decryptor,
                    CryptoStreamMode.Read);


                byte[] plainTextBytes = new byte[cipherTextBytes.Length];


                int decryptedByteCount = cryptoStream.Read(plainTextBytes,
                    0,
                    plainTextBytes.Length);

                memoryStream.Close();
                cryptoStream.Close();


                string t_plainText = Encoding.UTF8.GetString(plainTextBytes,
                    0,
                    decryptedByteCount);


                return t_plainText;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static string Decrypt(string p_cipherText, string p_passPhrase)
        {
            try
            {
                return Decrypt(p_cipherText, p_passPhrase, "@U$win");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static string DecryptPassword(string p_cipherText)
        {
            try
            {
                return Decrypt(p_cipherText, PasswKeyToEncrypt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static string ToEncrypt(string p_plainText, string p_passPhrase)
        {
            try
            {
                return ToEncrypt(p_plainText, p_passPhrase, "@U$win");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static string ToEncryptPassword(string plainTextPassw)
        {
            try
            {
                return ToEncrypt(plainTextPassw, PasswKeyToEncrypt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
